extends Node2D


enum GameState {
    PLAYING,
    PAUSED,
    CHOOSE_BUFF,
    GAME_OVER,
}


const update_buff_time: int = 10
@export var player: Player
@export var enemies: Node2D
@export var bullets: Node2D
@export var top_ui: CanvasLayer
@export var pause_panel: Panel
@export var buffs_panel: BuffPanel
@export var game_over_panel: Panel
@export var max_enemy_count: int = 10
@export var create_enemies_range: int = 100
@export var enemy_health: int = Settings.ENEMY_INIT_MAX_HEALTH
@export var enemy_speed: int = Settings.ENEMY_INIT_SPEED
@export var enemy_health_increment: int = 100
@export var enemy_speed_increment: int = 5
var _last_update_buff_time: int = 0
var _curr_state: GameState = GameState.PLAYING



func _ready() -> void:
    player.died.connect(
        func():
            _switch_state(GameState.GAME_OVER)
    )
    
    buffs_panel.choose_buff_finished.connect(
        func():
            _switch_state(GameState.PLAYING)
    )
    
    game_over_panel.get_node("RestartBtn").pressed.connect(
        func():
            var t_e = enemies.get_children().duplicate()
            for enemy in t_e:
                enemies.remove_child(enemy)
                enemy.queue_free()
            
            var t_b = bullets.get_children().duplicate()
            for bullet in t_b:
                bullets.remove_child(bullet)
                bullet.queue_free()
            
            player.load_data()
            player.global_position = get_viewport_rect().get_center()
            player.velocity = Vector2.ZERO
            enemy_health = Settings.ENEMY_INIT_MAX_HEALTH
            enemy_speed = Settings.ENEMY_INIT_SPEED
            
            _last_update_buff_time = TimeManager.get_playing_ticks_msec()
            _switch_state(GameState.PLAYING)
    )
    
    buffs_panel.hide()
    pause_panel.hide()
    game_over_panel.hide()
    _last_update_buff_time = TimeManager.get_playing_ticks_msec()


func _process(_delta: float) -> void:
    if get_tree().paused: return
    
    if enemies.get_child_count() < max_enemy_count:
        var n := randi_range(0, 3)
        var pos: Vector2
        match n:
            0: pos = Vector2(randi_range(0, get_viewport_rect().size.x), randi_range(-create_enemies_range, 0))
            1: pos = Vector2(randi_range(0, get_viewport_rect().size.x), randi_range(get_viewport_rect().size.y, get_viewport_rect().size.y + create_enemies_range))
            2: pos = Vector2(randi_range(-create_enemies_range, 0), randi_range(0, get_viewport_rect().size.y))
            3: pos = Vector2(randi_range(get_viewport_rect().size.x, get_viewport_rect().size.x + create_enemies_range), randi_range(0, get_viewport_rect().size.y))
        var enemy := preload("res://scene/enemy.tscn").instantiate() as Enemy
        enemy.setup(enemy_health, enemy_speed)
        enemy.global_position = pos
        enemies.add_child(enemy)
    
#    if not get_tree().paused:
    if TimeManager.get_playing_ticks_msec() - _last_update_buff_time >= update_buff_time * 1000:
        _switch_state(GameState.CHOOSE_BUFF)
        enemy_health += enemy_health_increment
        enemy_speed += enemy_speed_increment
        _last_update_buff_time = TimeManager.get_playing_ticks_msec()


func _input(event: InputEvent) -> void:
    if event.is_action_pressed("pause"):
        if _curr_state == GameState.PLAYING:
            _switch_state(GameState.PAUSED)
        elif _curr_state == GameState.PAUSED:
            _switch_state(GameState.PLAYING)
    if event.is_action_pressed("full_screen"):
        var mode := DisplayServer.window_get_mode()
        mode = DisplayServer.WINDOW_MODE_WINDOWED if mode == DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN else DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN
        DisplayServer.window_set_mode(mode)
        

func _switch_state(state: GameState) -> void:
    match state:
        GameState.PLAYING:
            TimeManager.pause(false)
            pause_panel.visible = false
            buffs_panel.display(false)
            game_over_panel.visible = false
        GameState.PAUSED:
            TimeManager.pause(true)
            pause_panel.visible = true
        GameState.CHOOSE_BUFF:
            TimeManager.pause(true)
            buffs_panel.display(true)
        GameState.GAME_OVER:
            TimeManager.pause(true)
            game_over_panel.visible = true
            top_ui.over_time = TimeManager.get_playing_ticks_msec()

    _curr_state = state
